package com.sjgtw.cloud.common.core.utils.encrypt;

import com.sjgtw.cloud.common.core.utils.SecurityUtils;
import org.apache.commons.codec.binary.Base64;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import java.io.UnsupportedEncodingException;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Arrays;

/**
 * <p>Title: RSA工具类</p>
 * <p>Description: </p>
 * @author Admin
 * @date 2020-9-28
 */
public class RSAUtils 
{
	public static void main(String[] args) throws Exception {
		String s1 = RSAUtils.pubKeyEncrypt("123456@Qwe", pubKey, "1");
		System.out.println(s1);


		String s = SecurityUtils.encryptPassword("123456789");
		System.out.println(s);

	}
	public static final String pubKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQClDvYy8/9TtotqQsElqvGaggz/sjvFi3DHd2PJq3L1MEZJMGhx65vFiClAMfvqY/UiN7Uel9JQeSVCv7z33c6A5gqPSzWyZ8Fmg2CYwJrahYCnW8mkIDqdLsduKYy4UN4gds62bsiylkVeb8tzKOkriFVX3514Von6XFNHQPM5iwIDAQAB";
	public static final String priKey = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAKUO9jLz/1O2i2pCwSWq8ZqCDP+yO8WLcMd3Y8mrcvUwRkkwaHHrm8WIKUAx++pj9SI3tR6X0lB5JUK/vPfdzoDmCo9LNbJnwWaDYJjAmtqFgKdbyaQgOp0ux24pjLhQ3iB2zrZuyLKWRV5vy3Mo6SuIVVffnXhWifpcU0dA8zmLAgMBAAECgYAa2lJHe9agIeSQhwexPxxLTLkcqDx9KPBSIyRC3Pe41/+3TH7Reck/26UKYpdfTJ/Gz1VSAtUebncXYuY1VQqRPvJU8RoT6xWV1rkhD2s6KKXwAFl1pyfSBSTsiV5BVTkHMblY2jKdceYnbsDTkpSKgOpUSTp/EGkfrvnsrAYuUQJBANNrpL/k68a6bGkB8vUmR5goAQ8E0G8O+3RQ4NZCjOlrA4cUIrkMZjQ/4faa/6rGq2NfkjmkZXD5X7WOrARBPU8CQQDH3LjO20rBQuKQt+A5IOIqL8Ska45JdSv1K40Hu9GFdEFqEscacslq0aO7mJnT5cam+x8fQVah8l9kH86GVskFAkAEQh7HXq0BC7AzTT6/gU3f2q5qxwYLtpmJ9jcRGbYM3YLsrZMldwJ3+vFqLiUII4hAMCSZ1J3WcK9k0MLWMxoxAkEApGhOYmOESByUMcYAnh4NzfRDh5muj4DiqyirN9xpy6VJlk9iF8CrLcLMNKqgh+3xjzTuchCWilvN2phLlLjZXQJAGqLBOENsqAVNDZZDL2T1I9xb9lCPsTMARhyL1xiRvwzMew0k9GFsSRj7zSJBXhK4bc1tC8gaAyjMQmy6skotww==";


	/**
	 * <p>Title: RSA公钥加密</p>
	 * <p>Description: </p>令牌不能为空
	 * @param content  待加密内容
	 * @param publicKey 公钥
	 * @param point  模型
	 * @return  密文
	 * @throws Exception
	 */
	public static String pubKeyEncrypt(String content, String publicKey, String point) throws Exception 
	{
		byte[] decoded = Base64.decodeBase64(publicKey);
		RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA")
				.generatePublic(new X509EncodedKeySpec(decoded));
		// RSA加密
		Cipher cipher = Cipher.getInstance("RSA");
		cipher.init(Cipher.ENCRYPT_MODE, pubKey);
		//切割超过长度的秘文
		byte[] resultBytes = getMaxResultEncrypt(content, point, cipher);
		String outStr = Base64.encodeBase64String(resultBytes);
		return outStr;
	}
	
	/**
	 * <p>Title: 切割超过长度的秘文</p>
	 * <p>Description: 默认117字节</p>
	 * @param content  待加密内容
	 * @param point  模型
	 * @return  密文
	 * @throws IllegalBlockSizeException
	 * @throws BadPaddingException
	 */
	private static byte[] getMaxResultEncrypt(String content, String point, Cipher cipher)
			throws IllegalBlockSizeException, BadPaddingException 
	{
		byte[] inputArray = content.getBytes();
		int inputLength = inputArray.length;
		// 默认117字节
		int MAX_ENCRYPT_BLOCK = 117;
		// 标识位
		int offSet = 0;
		byte[] resultBytes = {};
		byte[] cache = {};
		while (inputLength - offSet > 0) {
			if (inputLength - offSet > MAX_ENCRYPT_BLOCK) 
			{
				cache = cipher.doFinal(inputArray, offSet, MAX_ENCRYPT_BLOCK);
				offSet += MAX_ENCRYPT_BLOCK;
			} 
			else 
			{
				cache = cipher.doFinal(inputArray, offSet, inputLength - offSet);
				offSet = inputLength;
			}
			resultBytes = Arrays.copyOf(resultBytes, resultBytes.length + cache.length);
			System.arraycopy(cache, 0, resultBytes, resultBytes.length - cache.length, cache.length);
		}
		return resultBytes;
	}
	
	
	/**
	 * <p>Title: RSA私钥解密</p>
	 * <p>Description: </p>
	 * @param content  待解密内容
	 * @param publicKey 公钥
	 * @param point  模型
	 * @return 明文
	 * @throws Exception
	 */
	public static String priKeyDecrypt(String content, String privateKey, String point) throws Exception 
	{
		byte[] decoded = Base64.decodeBase64(privateKey);
		RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA")
				.generatePrivate(new PKCS8EncodedKeySpec(decoded));
		// RSA解密
		Cipher cipher = Cipher.getInstance("RSA");
		cipher.init(Cipher.DECRYPT_MODE, priKey);
		//切割超过长度的秘文后解密
		String outStr = new String(getMaxResultDecrypt(content, point, cipher));
		return outStr;
	}
	
	/**
	 * <p>Title: 切割超过长度的秘文</p>
	 * <p>Description: 默认128字节</p>
	 * @param content  待解密内容
	 * @param point  模型
	 * @return  密文
	 * @throws IllegalBlockSizeException
	 * @throws BadPaddingException
	 */
	private static byte[] getMaxResultDecrypt(String content, String point, Cipher cipher)
			throws IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException 
	{
		byte[] inputArray = Base64.decodeBase64(content.getBytes("UTF-8"));
		int inputLength = inputArray.length;
		// 默认128字节
		int MAX_ENCRYPT_BLOCK = 128;
		// 标识位
		int offSet = 0;
		byte[] resultBytes = {};
		byte[] cache = {};
		while (inputLength - offSet > 0) 
		{
			if (inputLength - offSet > MAX_ENCRYPT_BLOCK) {
				cache = cipher.doFinal(inputArray, offSet, MAX_ENCRYPT_BLOCK);
				offSet += MAX_ENCRYPT_BLOCK;
			} else {
				cache = cipher.doFinal(inputArray, offSet, inputLength - offSet);
				offSet = inputLength;
			}
			resultBytes = Arrays.copyOf(resultBytes, resultBytes.length + cache.length);
			System.arraycopy(cache, 0, resultBytes, resultBytes.length - cache.length, cache.length);
		}
		return resultBytes;
	}
}
